import UIKit
import DGCharts

class ViewController: UIViewController {
    // 折线图视图
    private let lineChartView = LineChartView()
    // 存储数据点（用于拖拽时更新）
    private var chartEntries: [ChartDataEntry] = []
    // 当前选中的点索引（用于拖拽中定位）
    private var selectedIndex: Int?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupChartView()       // 配置图表基础属性
        loadInitialData()      // 加载初始数据
        setupDragGesture()     // 添加拖拽手势
    }
    
    // 1. 配置图表基础属性
    private func setupChartView() {
        // 添加图表到视图
        view.addSubview(lineChartView)
        lineChartView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            lineChartView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            lineChartView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            lineChartView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            lineChartView.heightAnchor.constraint(equalToConstant: 400)
        ])
        
        // 基本配置：禁用缩放/拖拽（避免与自定义拖拽冲突）
        lineChartView.setScaleEnabled(false)
        lineChartView.pinchZoomEnabled = false
        lineChartView.doubleTapToZoomEnabled = false
        lineChartView.dragEnabled = false
        
        // 图表标题和描述
        lineChartView.chartDescription.text = "可拖拽折线图（拖动数据点调整曲线）"
        lineChartView.chartDescription.font = .systemFont(ofSize: 12)
        
        // 坐标轴配置
        lineChartView.xAxis.labelPosition = .bottom  // X轴标签在底部
        lineChartView.xAxis.axisMinimum = 0          // X轴最小值
        lineChartView.xAxis.axisMaximum = 10         // X轴最大值
        lineChartView.leftAxis.axisMinimum = 0       // Y轴最小值
        lineChartView.leftAxis.axisMaximum = 100     // Y轴最大值（限制拖拽范围）
        lineChartView.rightAxis.enabled = false      // 隐藏右轴
    }
    
    // 2. 加载初始数据
    private func loadInitialData() {
        // 初始化5个数据点（X从1到9，Y随机分布在20~80）
        chartEntries = [
            ChartDataEntry(x: 1, y: 30),
            ChartDataEntry(x: 3, y: 60),
            ChartDataEntry(x: 5, y: 40),
            ChartDataEntry(x: 7, y: 80),
            ChartDataEntry(x: 9, y: 50)
        ]
        
        // 配置数据集样式
        let dataSet = LineChartDataSet(entries: chartEntries, label: "数值")
        dataSet.lineWidth = 2.5                  // 线宽
        dataSet.setColor(.systemBlue)            // 线条颜色
        dataSet.circleRadius = 8                 // 数据点大小（便于触摸）
        dataSet.circleHoleRadius = 4             // 数据点内圆大小
        dataSet.setCircleColor(.systemBlue)      // 数据点颜色
        dataSet.highlightColor = .systemRed      // 选中时高亮颜色
        dataSet.highlightLineWidth = 1           // 高亮线宽
        
        // 设置图表数据
        lineChartView.data = LineChartData(dataSet: dataSet)
    }
    
    // 3. 添加拖拽手势
    private func setupDragGesture() {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
        lineChartView.addGestureRecognizer(panGesture)
    }
    
    // 4. 处理拖拽逻辑
    @objc private func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
        guard var dataSet = lineChartView.data?.dataSets.first as? LineChartDataSet else { return }
        
        switch gesture.state {
        case .began:
            // 拖拽开始：找到触摸点对应的最近数据点
            let touchLocation = gesture.location(in: lineChartView)
            selectedIndex = findClosestEntryIndex(to: touchLocation, tolerance: 30)  // 30像素容错范围
            
        case .changed:
            // 拖拽中：更新选中数据点的Y值
            guard let index = selectedIndex else { return }
            let touchLocation = gesture.location(in: lineChartView)
            
            // 将触摸点的Y坐标转换为图表的数值（关键：坐标系转换）
            
            let entry = chartEntries[index]
//            var entryPoint = lineChartView.getPosition(entry: entry, axis: .left)
            
//            let yValue = lineChartView.getAxisValue(touchLocation.y, axis: .left)
            
            let yValue = lineChartView.getTransformer(forAxis: .left).valueForTouchPoint(touchLocation).y
            
            // 限制Y值在0~100之间（避免超出坐标轴范围）
            let clampedY = max(0, min(100, yValue))
            
            // 更新数据点
            entry.y = clampedY
//            dataSet.replaceEntry(at: index, with: chartEntries[index])
            
            // 刷新图表（实时更新曲线）
            lineChartView.data?.notifyDataChanged()
            lineChartView.notifyDataSetChanged()
            
        case .ended, .cancelled:
            // 拖拽结束：清除选中状态并打印结果
            selectedIndex = nil
            print("拖拽结束，最终数据：\(chartEntries.map { String(format: "%.1f", $0.y) })")
            
        default:
            break
        }
    }
    
    // 5. 查找距离触摸点最近的数据点（返回索引）
    private func findClosestEntryIndex(to touchPoint: CGPoint, tolerance: CGFloat) -> Int? {
        for (index, entry) in chartEntries.enumerated() {
            // 将数据点的(X,Y)转换为屏幕坐标
            let entryPoint = lineChartView.getPosition(entry: entry, axis: .left)
            
            // 计算触摸点与数据点的距离
            let distance = hypot(touchPoint.x - entryPoint.x, touchPoint.y - entryPoint.y)
            
            // 如果在容错范围内，返回该点索引
            if distance <= tolerance {
                return index
            }
        }
        return nil
    }
}
